package semant.first_pass;

import semant.Env;
import symbol.ClassInfo;
import symbol.Symbol;
import syntaxtree.ClassDecl;
import syntaxtree.ClassDeclExtends;
import syntaxtree.ClassDeclSimple;
import syntaxtree.VisitorAdapter;

/**
 * 
 * @author gabriel
 * 
 */
public class ClassDeclHandler extends VisitorAdapter {

	private Env env;

	private ClassDeclHandler(Env e) {
		super();
		env = e;
	}

	public static void firstPass(Env env, ClassDecl cd) {
		ClassDeclHandler h = new ClassDeclHandler(env);
		cd.accept(h);
	}

	@Override
	public void visit(ClassDeclSimple node) {
		Symbol name = Symbol.symbol(node.name.s);
		ClassInfo info = new ClassInfo(name);

		// processando os atributos da classe
		AtributeListHandler.firstPass(env, info, node.varList);

		// processando os metodos da classe
		MethodDeclListHandler.firstPass(env, info, node.methodList);

		// insere a classe na tabela de simbolos da ENV
		if (!env.classes.put(name, info)) {
			env.err.Error(node.name, new Object[] {
				"Redeclaracao da classe: \'" + name + "\'.",
				"Declararacao anterior em: [" + node.name.line + ", " + node.name.row + "]"
			});
		}
	}

	@Override
	public void visit(ClassDeclExtends node) {
		Symbol name = Symbol.symbol(node.name.s);
		ClassInfo info = new ClassInfo(name);

		// processando os atributos da classe
		AtributeListHandler.firstPass(env, info, node.varList);

		// processando os metodos da clase
		MethodDeclListHandler.firstPass(env, info, node.methodList);

		// insere a classe na tabela de simbolos da ENV
		if (!env.classes.put(name, info)) {
			env.err.Error(node.name, new Object[] {
				"Redeclaracao da classe: \'" + name + "\'.",
				"Declaracao anterior em: [" + node.name.line + ", " + node.name.row + "]"
			});
		}

	}

}
